package com.xiaodu.dynamicdatasource.config;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilderCustomizer;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: dutianjie
 * @date: 2021/4/22
 * @version: v1.0.0
 * @description: 描述
 **/

//@Configuration
//@ConditionalOnClass({EntityManager.class})
//@EnableJpaRepositories(basePackages = {"com.xiaodu.dynamicdatasource.repository"})
//@EntityScan({"com.xiaodu.dynamicdatasource.entity"})
//@EnableTransactionManagement
public class JpaConfig {


    private DynamicDataSource dynamicDataSource;

    private JpaProperties jpaProperties;
//
    private Map<DBplatform, String> dbPlatform = new HashMap<>();

    public JpaConfig(DynamicDataSource dynamicDataSource, JpaProperties jpaProperties) {
        this.dynamicDataSource = dynamicDataSource;
        this.jpaProperties = jpaProperties;
        Map<String, String> properties = jpaProperties.getProperties();
        DBplatform[] values = DBplatform.values();
        Arrays.stream(values).forEach(e -> {
        String val = properties.get(e.db());
            dbPlatform.put(e, val);
        });

    }

    @Bean
    public LocalContainerEntityManagerFactoryBean pgEntityManager(EntityManagerFactoryBuilder entityManagerFactoryBuilder) {
        Map<String ,String> properties = jpaProperties.getProperties();
        properties.put("databasePlatform", dbPlatform.get(DBplatform.PSOTGRESQL));
       return entityManagerFactoryBuilder.dataSource(this.dynamicDataSource)
                .properties(properties)
                .packages("com.xiaodu.dynamicdatasource.repository")
                .persistenceUnit("pgPersistence")
                .build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean mysqlEntityManager(EntityManagerFactoryBuilder entityManagerFactoryBuilder) {
        Map<String ,String> properties = jpaProperties.getProperties();
        properties.put("databasePlatform", dbPlatform.get(DBplatform.MYSQL));
        return entityManagerFactoryBuilder.dataSource(this.dynamicDataSource)
                .properties(properties)
                .packages("com.xiaodu.dynamicdatasource.repository")
                .persistenceUnit("pgPersistence")
                .build();
    }


    @Bean
    public PlatformTransactionManager pgTransactionManager(LocalContainerEntityManagerFactoryBean pgEntityManager) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(pgEntityManager.getObject());
        return transactionManager;
    }

    @Bean
    public PlatformTransactionManager mysqlTransactionManager(LocalContainerEntityManagerFactoryBean mysqlEntityManager) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(mysqlEntityManager.getObject());
        return transactionManager;
    }
}
